﻿using UnityEngine;

// MeshBall 是一个 MonoBehaviour 脚本，用于在场景中高效地批量渲染多个 Mesh 实例
// 每个实例都有随机的位置、旋转、缩放，以及随机的颜色
// 通过使用 MaterialPropertyBlock 和 Graphics.DrawMeshInstanced 实现高性能的实例化渲染
public class MeshBall : MonoBehaviour
{
	// 定义 Shader 中 "_BaseColor" 属性的 ID，用于在 MaterialPropertyBlock 中高效设置颜色
	// 使用 Shader.PropertyToID() 可以避免字符串比较，提高性能和安全性
	static int baseColorId = Shader.PropertyToID("_BaseColor");

	// 序列化字段，在 Inspector 中可以手动指定要渲染的 Mesh 和 Material
	[SerializeField]
	Mesh mesh = default;         // 要渲染的网格（比如一个球体 Mesh）

	[SerializeField]
	Material material = default; // 要使用的材质（需支持 _BaseColor 属性，比如 Unlit 或支持颜色自定义的 Shader）

	// 用于存储 1023 个实例的变换矩阵（位置、旋转、缩放）
	Matrix4x4[] matrices = new Matrix4x4[1023];

	// 用于存储 1023 个实例的基础颜色（RGBA，作为 Vector4 存储）
	Vector4[] baseColors = new Vector4[1023];

	// MaterialPropertyBlock 用于批量设置材质属性（比如颜色），避免为每个实例创建独立材质
	MaterialPropertyBlock block;

	/// <summary>
	/// Awake 方法在脚本初始化时调用一次（比如场景加载、对象激活时）
	/// 这里用于初始化 1023 个球体的变换和颜色数据
	/// </summary>
	void Awake()
	{
		// 遍历所有 1023 个实例
		for (int i = 0; i < matrices.Length; i++)
		{
			// 为每个实例生成一个随机的变换矩阵（位置、旋转、缩放）
			matrices[i] = Matrix4x4.TRS(
				// 位置：在单位球体内随机生成一个点，然后放大到 10 米范围
				Random.insideUnitSphere * 10f,

				// 旋转：绕 X/Y/Z 轴各随机旋转 0~360 度
				Quaternion.Euler(
					Random.value * 360f,
					Random.value * 360f,
					Random.value * 360f
				),

				// 缩放：每个方向都统一缩放，范围为 0.5 ~ 1.5 倍
				Vector3.one * Random.Range(0.5f, 1.5f)
			);

			// 为每个实例生成一个随机的 BaseColor（RGBA，A 透明度范围为 0.5 ~ 1.0）
			baseColors[i] =
				new Vector4(
					Random.value,     // R
					Random.value,     // G
					Random.value,     // B
					Random.Range(0.5f, 1f) // A（透明度，半透明到不透明）
				);
		}
	}

	/// <summary>
	/// Update 方法每帧调用一次
	/// 这里使用 Graphics.DrawMeshInstanced 高效地一次性绘制所有 1023 个 Mesh 实例
	/// </summary>
	void Update()
	{
		// 如果 MaterialPropertyBlock 还未初始化，则创建一个，并设置颜色数组
		if (block == null)
		{
			block = new MaterialPropertyBlock();
			// 将 baseColors 数组设置到 Shader 的 _BaseColor 属性中
			block.SetVectorArray(baseColorId, baseColors);
		}

		// 执行实例化渲染：
		// - mesh：要渲染的网格
		// - submeshIndex：0，表示使用 Mesh 的第一个子网格
		// - material：使用的材质
		// - matrices：每个实例的变换矩阵（1023 个）
		// - instanceCount：实例数量，这里是 1023
		// - block：材质属性块，用于设置颜色等属性
		Graphics.DrawMeshInstanced(
			mesh, 0, material, matrices, 1023, block
		);
	}
}